package com.chat.handler;

import com.netty.imp.IMMessage;
import com.netty.imp.IMP;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * 心跳检测
 *
 * @author kewei
 */
public class HeartBeatHandler extends SimpleChannelInboundHandler<IMMessage> {

    int readIdleTimes = 0;

    /**
     * Is called for each message of type {@link I}.
     *
     * @param ctx the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler}
     *            belongs to
     * @param msg the message to handle
     * @throws Exception is thrown if an error occurred
     */
    @Override
    protected void messageReceived(ChannelHandlerContext ctx, IMMessage msg) throws Exception {
        if (IMP.PING.name().equals(msg.getCmd())) {
            msg.setTime(System.currentTimeMillis());
            msg.setContent("copy that");
            msg.setSender(IMP.SYSTEM.name());
            msg.setCmd(IMP.PONG.name());
            ctx.channel().writeAndFlush(msg);
        } else {
            ctx.fireChannelRead(msg);
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IdleStateEvent event = (IdleStateEvent) evt;

        String eventType = null;
        switch (event.state()) {
            case READER_IDLE:
                eventType = "读空闲";
                readIdleTimes++; // 读空闲的计数加1
                break;
            case WRITER_IDLE:
                eventType = "写空闲";
                // 不处理
                break;
            case ALL_IDLE:
                eventType = "读写空闲";
                // 不处理
                break;
        }
        if (readIdleTimes > 3) {
            System.out.println(" [server]读空闲超过3次，关闭连接");
            ctx.channel().writeAndFlush(new IMMessage(IMP.CLOSE.name(), System.currentTimeMillis(), IMP.SYSTEM.name(), "you are out!"));
            ctx.channel().close();
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
    }
}
